﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace PeteBrown.ConferenceTrivia.Controls
{
    // will randomly place, tilt, and scale items. Items in back will be smaller than those in the front
    public class GraveyardPanel : Panel
    {
        public double ItemFarScale
        {
            get { return (double)GetValue(ItemFarScaleProperty); }
            set { SetValue(ItemFarScaleProperty, value); }
        }

        public static readonly DependencyProperty ItemFarScaleProperty =
            DependencyProperty.Register("ItemFarScale", typeof(double), typeof(GraveyardPanel), new PropertyMetadata(0.25));


        public double ItemNearScale
        {
            get { return (double)GetValue(ItemNearScaleProperty); }
            set { SetValue(ItemNearScaleProperty, value); }
        }

        public static readonly DependencyProperty ItemNearScaleProperty =
            DependencyProperty.Register("ItemNearScale", typeof(double), typeof(GraveyardPanel), new PropertyMetadata(1.0));




        public int ItemForegroundCount
        {
            get { return (int)GetValue(ItemForegroundCountProperty); }
            set { SetValue(ItemForegroundCountProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ItemForegroundCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemForegroundCountProperty =
            DependencyProperty.Register("ItemForegroundCount", typeof(int), typeof(GraveyardPanel), new PropertyMetadata(1));


        public int ItemBackgroundRows
        {
            get { return (int)GetValue(ItemBackgroundRowsProperty); }
            set { SetValue(ItemBackgroundRowsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ItemForegroundCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemBackgroundRowsProperty =
            DependencyProperty.Register("ItemBackgroundRows", typeof(int), typeof(GraveyardPanel), new PropertyMetadata(2));




        public int BackgroundPositionJitter
        {
            get { return (int)GetValue(BackgroundPositionJitterProperty); }
            set { SetValue(BackgroundPositionJitterProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BackgroundPositionJitter.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BackgroundPositionJitterProperty =
            DependencyProperty.Register("BackgroundPositionJitter", typeof(int), typeof(GraveyardPanel), new PropertyMetadata(15));

        


        protected override Size MeasureOverride(Size availableSize)
        {
            Size desiredSize = new Size();

            if (Children.Count > 0)
            {
                Size backgroundSize = new Size(availableSize.Width * 0.65 / (Children.Count / ItemBackgroundRows),
                                               availableSize.Height / ItemBackgroundRows);

                Size foregroundSize = new Size(availableSize.Width * 0.35 / ItemForegroundCount,
                                               availableSize.Height); ;

                int currentChild = 0;
                foreach (UIElement element in Children)
                {
                    // Resize based on position in collection
                    if (Children.Count - currentChild - 1 == ItemForegroundCount)
                    {
                        // foreground
                        element.Measure(foregroundSize);

                    }
                    else
                    {
                        // background
                        element.Measure(backgroundSize);

                        desiredSize.Width += element.DesiredSize.Width;
                        desiredSize.Height += element.DesiredSize.Height;

                    }

                    currentChild++;
                }


            }
            else
            {
                desiredSize = new Size(0, 0);
            }

            if (double.IsInfinity(availableSize.Height) ||
                double.IsInfinity(availableSize.Width))

                return desiredSize;
            else
                return availableSize;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            // for now, cluster background to left and foreground to right

            int currentChild = 0;
            Random random = new Random();
            int currentRow = 1;
            int currentColumn = 0;
            int elementsPerRow = (Children.Count - ItemForegroundCount) / ItemBackgroundRows;

            double backgroundStartX = finalSize.Width *.35;
            double backgroundStartY = 0;

            foreach (UIElement element in Children)
            {
                double x, y;

                if (Children.Count - currentChild - 1 == ItemForegroundCount)
                {
                    // foreground
                    // TODO: assumes only one element
                    x = random.Next(-50, 50);
                    y = random.Next(-50,50);
                    
                }
                else
                {
                    // background

                    currentColumn += 1;
                    if (currentColumn > elementsPerRow)
                    {
                        currentColumn = 1;
                        currentRow += 1;
                    }

                    x = backgroundStartX + (currentColumn - 1) * element.DesiredSize.Width + random.Next(BackgroundPositionJitter * -1, BackgroundPositionJitter);
                    y = backgroundStartY + (currentRow - 1) * element.DesiredSize.Height + random.Next(BackgroundPositionJitter * -1, BackgroundPositionJitter);
                }

                Rect finalRect = new Rect(x, y, element.DesiredSize.Width, element.DesiredSize.Height);

                element.Arrange(finalRect);


                // now add a rotate transform to the element

                element.RenderTransform = new RotateTransform();
                ((RotateTransform)element.RenderTransform).Angle = random.Next(-4, 4);

                currentChild++;
            }

            
            // start animation timers to actually display elements


            return finalSize;
        }

    }
}
